package com.xiyu.service.repository.restaurant.plan;

import com.xiyu.service.model.restaurant.dish.RestaurantDishFetcher;
import com.xiyu.service.model.restaurant.plan.RestaurantPlan;
import com.xiyu.service.model.restaurant.plan.RestaurantPlanDetailFetcher;
import com.xiyu.service.model.restaurant.plan.RestaurantPlanFetcher;
import com.xiyu.service.model.restaurant.plan.RestaurantPlanTable;
import com.xiyu.service.model.restaurant.recipe.RestaurantComboFetcher;
import com.xiyu.service.vo.restaurant.plan.PlanQueryInput;
import org.babyfish.jimmer.spring.repository.JRepository;
import org.babyfish.jimmer.sql.ast.Predicate;
import org.babyfish.jimmer.Page;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Optional;

public interface RestaurantPlanRepository extends JRepository<RestaurantPlan, Long> {
    RestaurantPlanTable restaurantPlanTable = RestaurantPlanTable.$;

    default Page<RestaurantPlan> pageQuery(PlanQueryInput inputVO){
        return sql().createQuery(restaurantPlanTable)
                .whereIf(StringUtils.hasText(inputVO.getPlanNo()), () -> restaurantPlanTable.planNo().like(inputVO.getPlanNo()))
                .whereIf(inputVO.getPlanStatus() != null, restaurantPlanTable.planStatus().eq(inputVO.getPlanStatus()))
                .whereIf(inputVO.getComboId() != null, restaurantPlanTable.comboId().eq(inputVO.getComboId()))
                .orderBy(restaurantPlanTable.id().desc())
                .select(restaurantPlanTable.fetch(RestaurantPlanFetcher.$.allTableFields().combo(RestaurantComboFetcher.$.allTableFields())))
                .fetchPage(inputVO.getPageNo() - 1, inputVO.getPageSize());
    }

    default void updateStatus(Long id, Integer status){
        sql().createUpdate(restaurantPlanTable)
                .set(restaurantPlanTable.planStatus(), status)
                .where(restaurantPlanTable.id().eq(id))
                .execute();
    }

    default Optional<RestaurantPlan> getDetailById(Long id){
        return sql().createQuery(restaurantPlanTable)
                .where(restaurantPlanTable.id().eq(id))
                .select(restaurantPlanTable.fetch(RestaurantPlanFetcher.$.allTableFields()
                        .details(RestaurantPlanDetailFetcher.$.allTableFields()
                                .dish(RestaurantDishFetcher.$.allTableFields()))))
                .fetchOptional();
    }

    Optional<RestaurantPlan> findByPlanName(String planName);

    default Optional<RestaurantPlan> findDuplicateTimePlan(LocalDateTime beginTime, LocalDateTime endTime){
        return sql().createQuery(restaurantPlanTable)
                .where(Predicate.or(
                        Predicate.and(restaurantPlanTable.beginTime().le(beginTime), restaurantPlanTable.endTime().ge(beginTime)),
                        Predicate.and(restaurantPlanTable.beginTime().le(endTime), restaurantPlanTable.endTime().ge(endTime))
                ))
                .select(restaurantPlanTable)
                .fetchOptional();
    }
}